#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>//共享内存
#include <time.h>
#include <string.h>
#define  INMSG_PATH  "/dev/memfifo" //数据入口，可以是串口，网口，这里模拟缓存
//定义数据的结构体，这个依赖具体情况，这里只模拟三个数据
#define CARMAX     10  //总共的车的路数
typedef struct 
{
     int car_id; // 车号
     int car_place;//车在最近的站点
     int car_time_hour;//车到站时间
     int car_time_min;
     
} car_info;

const char *wday[] = 
{ "星期天","星期一","星期二","星期三","星期四","星期五","星期六"
};
void showMsg(int* msg);
void showHead(void);//信息头
void showTail(void);   
void showMsg(int* msg);



int main(int argc, char **argv)
{
     int fd_memfifo;
     car_info *p_map;//共享缓冲区的地址
     int ret;
     int msg[4];
     int retval;
     int i;
	  
     fd_memfifo = open(INMSG_PATH,O_RDWR);
     if(fd_memfifo == -1)
     {
	  printf("open INMSG_PATH failed\n");
	  
	  return -1;
	  
     }
     p_map = (car_info*)mmap(NULL,sizeof(car_info)*CARMAX,PROT_READ|PROT_WRITE,
			     MAP_SHARED|MAP_ANONYMOUS,-1,0);
     
     //父进程用于发布数据，子进程获取数据
     ret = fork();
     if(ret < 0)
     {
	  printf("fork error \n");
	  return -1;
	  
     }
     
     if(ret == 0)
     {
	
	  while(1)
	  {
	       retval =  read(fd_memfifo,(void*)msg,4*4);
	       i = msg[0]%10;//保证数值在10以内
	       msg[0] += 1;
	       
	       if(retval == 16)
	       {
		    //用读取来的数据更改共享区
		    memcpy(&(*(p_map+i)).car_id,&msg[0],4);
		    memcpy(&(*(p_map+i)).car_place,&msg[1],4);
		    memcpy(&(*(p_map+i)).car_time_hour,&msg[2],4);
		    memcpy(&(*(p_map+i)).car_time_min,&msg[3],4);
		    
	       }
	  
	     
	  }
	  
     }

     if(ret > 0)
     {
	  //parent进程信息发布
	  //从共享类存中读取数据并发布
	
	  while(1)
	  {
	       //   sleep(5);//每隔5s发布一次数据
	       showHead();
	       
	       for(i = 0; i<CARMAX; i++)
	       {
		    memcpy(msg,p_map+i,4*4);
		    /*
		    memcpy(&msg[0],(*(p_map+i)).car_id,4);
		    memcpy(&msg[1],(*(p_map+i)).car_place,4);
		    memcpy(&msg[2],(*(p_map+i)).car_time_hour,4);
		    memcpy(&msg[3],(*(p_map+i)).car_time_min,4);
		    */
		    showMsg(msg);
	       
	       }
	  
	       showTail();
	       sleep(3);
	       
	  }
	  
	  
     }
     
  return 0;
}



void showMsg(int* msg)
{
     
     int wait_hour;
     int wait_min;
     
      time_t now;
     struct tm *p;
     time(&now);
     p = localtime(&now);//取得当前时间

     wait_hour = abs( p->tm_hour - msg[2]);
     wait_min  = abs(p->tm_min  - msg[3]);
     
     
     printf("       %02d              %02d           %02d:%02d        %02d小时%02d分         \n",msg[0],msg[1],msg[2],msg[3],wait_hour,wait_min);
}

void showHead(void)
{
     system("clear");
     
      printf("************************************************************\n");
     printf("*                    公交信息发布系统                      *\n");
     printf("公交车次    现在所在站点      大概到站时间   大概等待时间               \n");
     
}

void showTail(void)
{
     time_t now;
     struct tm *p;
     time(&now);
     p = localtime(&now);//取得当前时间
     
     printf( "现在时间 %d-%d-%d %s %d:%d                               荆州公交总公司\n",(1900+p->tm_year),(1 + p->tm_mon),p->tm_mday,wday[p->tm_wday],p->tm_hour,p->tm_min  );
}
